// 墨滴插件 - 目录功能优化版本
class MdniceTocPlugin {
  constructor() {
    this.originMenuList = [];
    this.menuUpdateInterval = null;
    this.isInitialized = false;
    this.scrollHandler = null;
    this.isUserScrollingMenu = false; // 标记用户是否正在滚动目录
    this.menuScrollTimeout = null; // 菜单滚动超时定时器
    this.isProgrammaticScroll = false; // 标记是否是程序触发的滚动
    this.mutationObserver = null; // 新增：DOM变化监听器
    this.config = {
      updateInterval: 2000, // 菜单更新间隔
      titleTags: ["h1", "h2", "h3", "h4", "h5", "h6"],
      menuStyles: {
        background: "#ffffff",
        border: "1px solid #e0e0e0",
        borderRadius: "8px",
        boxShadow: "0 2px 10px rgba(0,0,0,0.1)",
        color: "#333333",
        fontSize: "14px",
        lineHeight: "1.6",
        // maxHeight: "80vh",
        minWidth: "200px",
        padding: "12px",
        zIndex: "9999",
        width: "22%",
        height: "80vh",
      },
    };
  }

  resizePage(width = "calc(100% - 46px)") {
    const container = document.querySelector(".nice-text-container");
    if (!container) return;

    container.style.width = width;
    const articleListIcon = document.querySelector(
      "#basic-sidebar-container > div.top-container > .btn-container-active"
    );
    if (!articleListIcon || !articleListIcon.click) return;
    articleListIcon.click();
  }
  // 初始化插件
  init() {
    if (this.isInitialized) return;

    try {
      this.waitForElements().then(() => {
        this.addToggleButton();
        this.createMenuPanel();
        this.setupScrollSync(); // 只保留滚动同步，移除定时更新
        this.setupContentObserver(); // 新增：设置内容变化监听
        this.checkDefaultShowMenu();
        this.isInitialized = true;
        console.log("墨滴目录插件初始化成功");
      });
    } catch (error) {
      console.error("墨滴目录插件初始化失败:", error);
    }
  }

  // 显示加载状态
  showLoadingState() {
    const menu = document.querySelector("#mdniceMenu");
    if (!menu) return;

    menu.innerHTML = `
      <div style="
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 20px;
        color: #666;
        font-size: 14px;
      ">
        <div style="
          width: 16px;
          height: 16px;
          border: 2px solid #e0e0e0;
          border-top: 2px solid #1890ff;
          border-radius: 50%;
          animation: spin 1s linear infinite;
          margin-right: 8px;
        "></div>
        <span>正在加载目录...</span>
      </div>
      <style>
        @keyframes spin {
          0% { transform: rotate(0deg); }
          100% { transform: rotate(360deg); }
        }
      </style>
    `;
  }

  // 检查是否默认显示菜单
  async checkDefaultShowMenu() {
    try {
      const result = await chrome.storage.sync.get(["mdniceTocConfig"]);
      if (result.mdniceTocConfig && result.mdniceTocConfig.defaultShowMenu) {
        // 延迟一下确保菜单已经创建完成
        setTimeout(() => {
          this.toggleMenu();
          // 显示加载状态
          this.showLoadingState();
        }, 500);
      }
    } catch (error) {
      console.error("读取配置失败:", error);
    }
  }

  // 等待必要元素加载完成
  async waitForElements() {
    const maxAttempts = 50; // 最多等待10秒
    let attempts = 0;

    while (attempts < maxAttempts) {
      const sidebar = document.querySelector("#nice-sidebar");
      const richTextBox = document.querySelector("#nice-rich-text-box");

      if (sidebar && richTextBox) {
        return true;
      }

      await this.delay(200);
      attempts++;
    }

    throw new Error("页面元素加载超时");
  }

  // 延迟函数
  delay(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms));
  }

  // 添加切换按钮
  addToggleButton() {
    const btnBox = document.querySelector("#nice-sidebar");
    if (!btnBox || document.querySelector("#nice-sidebar-menu-type")) return;

    const svg = this.createToggleIcon();
    const menuBtn = document.createElement("a");
    menuBtn.id = "nice-sidebar-menu-type";
    menuBtn.classList.add("nice-btn-previewtype");
    menuBtn.innerHTML = svg;
    menuBtn.title = "显示/隐藏目录";
    menuBtn.style.cursor = "pointer";

    // 添加点击事件
    menuBtn.addEventListener("click", (e) => {
      e.preventDefault();
      this.toggleMenu();
    });

    btnBox.appendChild(menuBtn);
  }

  // 创建切换图标
  createToggleIcon() {
    return `<svg viewBox="0 0 1024 1024" width="16" height="16" fill="#1196db">
      <path d="M106.666667 192a21.333333 21.333333 0 1 0 0 42.666667h85.333333a21.333333 21.333333 0 0 0 0-42.666667H106.666667z m0 298.666667a21.333333 21.333333 0 0 0 0 42.666666h85.333333a21.333333 21.333333 0 0 0 0-42.666666H106.666667z m0 298.666666a21.333333 21.333333 0 0 0 0 42.666667h85.333333a21.333333 21.333333 0 0 0 0-42.666667H106.666667zM320 192a21.333333 21.333333 0 0 0 0 42.666667h597.333333a21.333333 21.333333 0 0 0 0-42.666667H320z m0 298.666667a21.333333 21.333333 0 0 0 0 42.666666h597.333333a21.333333 21.333333 0 0 0 0-42.666666H320z m0 298.666666a21.333333 21.333333 0 0 0 0 42.666667h597.333333a21.333333 21.333333 0 0 0 0-42.666667H320z"/>
    </svg>`;
  }

  // 切换菜单显示状态
  toggleMenu() {
    const menu = document.querySelector("#mdniceMenu");
    if (!menu) return;

    const isVisible = menu.style.display !== "none";
    menu.style.display = isVisible ? "none" : "block";

    // 添加动画效果
    if (!isVisible) {
      this.resizePage("80%");
      // 显示加载状态
      this.showLoadingState();
      menu.style.opacity = "0";
      menu.style.transform = "translateX(20px)";
      setTimeout(() => {
        menu.style.opacity = "1";
        menu.style.transform = "translateX(0)";
        // 更新菜单内容
        this.updateMenu(true);
      }, 10);
    } else {
      this.resizePage();
    }
  }

  // 获取标题元素列表
  getMenuItems() {
    const richTextBox = document.querySelector("#nice-rich-text-box");
    if (!richTextBox) return [];

    const menuList = [];
    this.config.titleTags.forEach((tag) => {
      const elements = richTextBox.querySelectorAll(tag);
      menuList.push(...Array.from(elements));
    });

    // 按位置排序
    return menuList.sort((a, b) => a.offsetTop - b.offsetTop);
  }

  // 创建菜单面板
  createMenuPanel() {
    if (document.querySelector("#mdniceMenu")) return;

    const btnBox = document.querySelector("#nice-sidebar");
    const menuBox = document.createElement("div");
    menuBox.id = "mdniceMenu";
    const container = document.querySelector(".nice-text-container");
    if (container) {
      this.config.menuStyles.height = `${container.clientHeight}px`;
    }

    // 应用样式
    Object.assign(menuBox.style, {
      position: "fixed",
      right: `${btnBox.offsetWidth + 10}px`,
      top: `${btnBox.offsetTop}px`,
      display: "none",
      overflow: "auto",
      wordBreak: "break-word",
      transition: "opacity 0.3s ease, transform 0.3s ease",
      ...this.config.menuStyles,
    });

    // 添加加载提示
    menuBox.innerHTML = `
      <div style="
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 20px;
        color: #666;
        font-size: 14px;
      ">
        <div style="
          width: 16px;
          height: 16px;
          border: 2px solid #e0e0e0;
          border-top: 2px solid #1890ff;
          border-radius: 50%;
          animation: spin 1s linear infinite;
          margin-right: 8px;
        "></div>
        <span>正在加载目录...</span>
      </div>
      <style>
        @keyframes spin {
          0% { transform: rotate(0deg); }
          100% { transform: rotate(360deg); }
        }
      </style>
    `;

    document.body.appendChild(menuBox);

    // 添加菜单滚动监听器
    this.setupMenuScrollListener();

    this.updateMenu();
  }

  // 新增：设置菜单滚动监听器
  setupMenuScrollListener() {
    const menu = document.querySelector("#mdniceMenu");
    if (!menu) return;

    menu.addEventListener("scroll", () => {
      // 标记用户正在滚动目录
      this.isUserScrollingMenu = true;

      // 清除之前的超时定时器
      if (this.menuScrollTimeout) {
        clearTimeout(this.menuScrollTimeout);
      }

      // 设置超时，用户停止滚动后恢复自动定位
      this.menuScrollTimeout = setTimeout(() => {
        this.isUserScrollingMenu = false;
      }, 1000); // 1秒后恢复自动定位
    });
  }

  // 设置滚动同步
  setupScrollSync() {
    const richTextBox = document.querySelector("#nice-rich-text-box");
    if (!richTextBox) return;

    // 移除之前的滚动监听器
    if (this.scrollHandler) {
      richTextBox.removeEventListener("scroll", this.scrollHandler);
    }

    // 创建新的滚动监听器
    this.scrollHandler = this.debounce(() => {
      // 如果用户正在滚动目录或程序正在滚动，跳过更新
      if (this.isUserScrollingMenu || this.isProgrammaticScroll) return;

      this.updateActiveMenuItem();
    }, 50);

    richTextBox.addEventListener("scroll", this.scrollHandler);
  }

  // 防抖函数
  debounce(func, wait) {
    let timeout;
    return function executedFunction(...args) {
      const later = () => {
        clearTimeout(timeout);
        func(...args);
      };
      clearTimeout(timeout);
      timeout = setTimeout(later, wait);
    };
  }

  // 更新当前活跃的菜单项
  updateActiveMenuItem() {
    const richTextBox = document.querySelector("#nice-rich-text-box");
    const menu = document.querySelector("#mdniceMenu");
    if (!richTextBox || !menu) return;

    const menuItems = this.getMenuItems();
    if (menuItems.length === 0) return;

    const scrollTop = richTextBox.scrollTop;
    const containerHeight = richTextBox.clientHeight;
    const scrollBottom = scrollTop + containerHeight;
    const viewportCenter = scrollTop + containerHeight / 2; // 视口中心点

    // 特殊处理：如果滚动到最顶部，直接选择第一个标题
    if (scrollTop <= 20 && menuItems.length > 0) {
      this.updateMenuActiveState(menuItems[0]);
      return;
    }

    // 计算每个标题的权重分数
    let bestItem = null;
    let bestScore = -Infinity;

    menuItems.forEach((item) => {
      const itemTop = item.offsetTop;
      const itemBottom = itemTop + item.offsetHeight;
      const itemCenter = itemTop + item.offsetHeight / 2;

      // 计算标题在视口中的可见程度
      const visibleTop = Math.max(itemTop, scrollTop);
      const visibleBottom = Math.min(itemBottom, scrollBottom);
      const visibleHeight = Math.max(0, visibleBottom - visibleTop);
      const visibilityRatio = visibleHeight / item.offsetHeight;

      // 计算标题到视口中心的距离
      const distanceToCenter = Math.abs(itemCenter - viewportCenter);
      const distanceScore = Math.max(0, 1 - distanceToCenter / containerHeight);

      // 标题层级权重（H1 > H2 > H3...）
      const level = parseInt(item.nodeName.slice(1));
      const levelWeight = Math.max(0.5, 1 - (level - 1) * 0.1);

      // 综合评分
      const score =
        visibilityRatio * 0.4 + distanceScore * 0.4 + levelWeight * 0.2;

      // 如果标题完全在视口上方，给予额外权重
      if (itemBottom <= scrollTop + 100) {
        const aboveScore = score + 0.3;
        if (aboveScore > bestScore) {
          bestScore = aboveScore;
          bestItem = item;
        }
      }
      // 如果标题在视口内或接近视口，正常评分
      else if (itemTop <= scrollBottom + 50) {
        if (score > bestScore) {
          bestScore = score;
          bestItem = item;
        }
      }
    });

    // 确保有活跃项
    if (!bestItem && menuItems.length > 0) {
      bestItem = menuItems[0];
    }

    // 更新菜单项的活跃状态
    this.updateMenuActiveState(bestItem);
  }

  // 更新菜单项的活跃状态
  updateMenuActiveState(activeItem) {
    const menu = document.querySelector("#mdniceMenu");
    if (!menu) return;

    const menuItems = menu.querySelectorAll("div[data-title-id]");
    menuItems.forEach((menuItem) => {
      menuItem.classList.remove("active");
      menuItem.style.backgroundColor = "transparent";
      menuItem.style.color = "#333333";
      menuItem.style.fontWeight = "400";
    });

    if (activeItem) {
      // 使用相同的文本清理逻辑
      const cleanText = activeItem.innerText
        .replace(/\s+/g, "")
        .replace(/[^\w\u4e00-\u9fa5]/g, "");

      const activeMenuItem = menu.querySelector(
        `[data-title-id="${cleanText}"]`
      );
      if (activeMenuItem) {
        activeMenuItem.classList.add("active");
        activeMenuItem.style.backgroundColor = "#e6f7ff";
        activeMenuItem.style.color = "#1890ff";
        activeMenuItem.style.fontWeight = "600";

        // 只有在用户没有主动滚动目录时才自动定位
        if (!this.isUserScrollingMenu) {
          this.ensureMenuItemVisible(activeMenuItem);
        }
      }
    }
  }

  // 确保菜单项在视口内可见
  ensureMenuItemVisible(menuItem) {
    const menu = document.querySelector("#mdniceMenu");
    if (!menu) return;

    const menuRect = menu.getBoundingClientRect();
    const itemRect = menuItem.getBoundingClientRect();

    // 如果菜单项不在视口内，滚动到可见位置
    if (itemRect.top < menuRect.top || itemRect.bottom > menuRect.bottom) {
      menuItem.scrollIntoView({
        behavior: "smooth",
        block: "nearest",
      });
    }
  }

  // 更新菜单内容
  updateMenu(isInit = false) {
    const menu = document.querySelector("#mdniceMenu");
    if (!menu) return;

    const menuItems = this.getMenuItems();
    const currentMenuHash = this.getMenuHash(menuItems);

    // 检查内容是否发生变化
    if (this.originMenuList === currentMenuHash && !isInit) return;

    this.originMenuList = currentMenuHash;
    this.renderMenu(menu, menuItems);

    // 更新活跃状态 - 移除setTimeout，直接调用
    this.updateActiveMenuItem();
  }

  // 生成菜单哈希值用于比较
  getMenuHash(menuItems) {
    return menuItems
      .map((item) => `${item.nodeName}${item.innerText}`)
      .join("|");
  }

  // 渲染菜单内容
  renderMenu(menuElement, menuItems) {
    if (menuItems.length === 0) {
      menuElement.innerHTML = `
        <div style="
          color: #999;
          text-align: center;
          padding: 20px;
          font-size: 14px;
        ">
          <div style="margin-bottom: 8px;">📝</div>
          <div>暂无标题</div>
          <div style="
            font-size: 12px;
            color: #ccc;
            margin-top: 4px;
          ">请在编辑器中添加标题（H1-H6）</div>
        </div>
      `;
      return;
    }

    menuElement.innerHTML = "";

    // 计算最小标题级别
    const minLevel = Math.min(
      ...menuItems.map((item) => parseInt(item.nodeName.slice(1)))
    );

    menuItems.forEach((item) => {
      const menuItem = this.createMenuItem(item, minLevel);
      menuElement.appendChild(menuItem);
    });
  }

  // 创建菜单项
  createMenuItem(item, minLevel) {
    const div = document.createElement("div");
    const level = parseInt(item.nodeName.slice(1));
    const indent = (level - minLevel) * 16;

    Object.assign(div.style, {
      padding: `8px 12px 8px ${indent + 12}px`,
      cursor: "pointer",
      borderBottom: "1px solid #f0f0f0",
      fontSize: `${Math.max(14 - (level - minLevel), 12)}px`,
      fontWeight: level <= 2 ? "600" : "400",
      transition: "background-color 0.2s ease, color 0.2s ease",
      whiteSpace: "nowrap",
      overflow: "hidden",
      textOverflow: "ellipsis",
    });

    // 显示内容保持原样，只清理用于选择器的ID
    const cleanText = item.innerText
      .replace(/\s+/g, "")
      .replace(/[^\w\u4e00-\u9fa5]/g, "");

    div.innerText = item.innerText.replace(/\s+/g, "");
    div.title = item.innerText;
    div.setAttribute("data-title-id", cleanText);

    // 添加事件监听器
    this.addMenuItemEvents(div, item);

    return div;
  }

  // 添加菜单项事件
  addMenuItemEvents(menuItem, targetElement) {
    // 点击跳转
    menuItem.addEventListener("click", (e) => {
      e.preventDefault();
      e.stopPropagation();

      // 重新查找目标元素，确保引用有效
      const richTextBox = document.querySelector("#nice-rich-text-box");
      if (!richTextBox) return;

      // 通过文本内容重新查找目标元素
      const targetText = menuItem.getAttribute("data-title-id");
      const allTitles = this.getMenuItems();
      const targetElement = allTitles.find((item) => {
        const cleanText = item.innerText
          .replace(/\s+/g, "")
          .replace(/[^\w\u4e00-\u9fa5]/g, "");
        return cleanText === targetText;
      });

      if (targetElement) {
        this.scrollToElement(targetElement);
      }
    });

    // 鼠标悬停效果
    menuItem.addEventListener("mouseenter", () => {
      if (!menuItem.classList.contains("active")) {
        menuItem.style.backgroundColor = "#f5f5f5";
        menuItem.style.color = "#1890ff";
      }
    });

    menuItem.addEventListener("mouseleave", () => {
      if (!menuItem.classList.contains("active")) {
        menuItem.style.backgroundColor = "transparent";
        menuItem.style.color = "#333333";
      }
    });
  }

  // 滚动到目标元素
  scrollToElement(element) {
    const richTextBox = document.querySelector("#nice-rich-text-box");
    if (!richTextBox || !element) {
      console.log("墨滴插件: 滚动失败 - 找不到编辑器或目标元素");
      return;
    }

    console.log("墨滴插件: 开始滚动到元素:", element.innerText);

    // 标记开始程序滚动
    this.isProgrammaticScroll = true;

    const targetTop = element.offsetTop;
    const scrollTop = targetTop - 50;

    // 立即更新活跃状态为目标元素
    this.updateMenuActiveState(element);

    richTextBox.scrollTo({
      top: Math.max(0, scrollTop),
      behavior: "smooth",
    });

    // 高亮目标元素
    this.highlightElement(element);

    // 等待滚动完成后恢复活跃目录更新
    this.waitForScrollComplete(() => {
      this.isProgrammaticScroll = false;
      // 延迟一下再更新活跃状态，确保滚动完全停止
      setTimeout(() => {
        this.updateActiveMenuItem();
      }, 100);
    });
  }

  // 高亮目标元素
  highlightElement(element) {
    const originalBackground = element.style.backgroundColor;
    element.style.backgroundColor = "#fff3cd";
    element.style.transition = "background-color 0.3s ease";

    setTimeout(() => {
      element.style.backgroundColor = originalBackground;
    }, 2000);
  }

  // 销毁插件
  destroy() {
    // 移除滚动监听器
    const richTextBox = document.querySelector("#nice-rich-text-box");
    if (richTextBox && this.scrollHandler) {
      richTextBox.removeEventListener("scroll", this.scrollHandler);
    }

    // 断开DOM变化监听器
    if (this.mutationObserver) {
      this.mutationObserver.disconnect();
      this.mutationObserver = null;
    }

    const menu = document.querySelector("#mdniceMenu");
    const button = document.querySelector("#nice-sidebar-menu-type");

    if (menu) menu.remove();
    if (button) button.remove();

    this.isInitialized = false;
  }

  // 设置内容变化监听器
  setupContentObserver() {
    const richTextBox = document.querySelector("#nice-rich-text-box");
    if (!richTextBox) return;

    // 如果已有监听器，先断开连接
    if (this.mutationObserver) {
      this.mutationObserver.disconnect();
    }

    // 创建新的监听器
    this.mutationObserver = new MutationObserver((mutations) => {
      let shouldUpdate = false;

      mutations.forEach((mutation) => {
        // 检查是否有标题相关的变化
        if (mutation.type === "childList") {
          // 新增或删除的节点
          mutation.addedNodes.forEach((node) => {
            if (node.nodeType === Node.ELEMENT_NODE) {
              if (
                this.config.titleTags.includes(node.nodeName.toLowerCase()) ||
                (node.querySelector &&
                  this.config.titleTags.some((tag) => node.querySelector(tag)))
              ) {
                shouldUpdate = true;
              }
            }
          });

          mutation.removedNodes.forEach((node) => {
            if (node.nodeType === Node.ELEMENT_NODE) {
              if (
                this.config.titleTags.includes(node.nodeName.toLowerCase()) ||
                (node.querySelector &&
                  this.config.titleTags.some((tag) => node.querySelector(tag)))
              ) {
                shouldUpdate = true;
              }
            }
          });
        } else if (
          mutation.type === "characterData" ||
          mutation.type === "attributes"
        ) {
          // 文本内容或属性变化
          const target = mutation.target;
          if (target.nodeType === Node.ELEMENT_NODE) {
            if (this.config.titleTags.includes(target.nodeName.toLowerCase())) {
              shouldUpdate = true;
            }
          } else if (target.nodeType === Node.TEXT_NODE) {
            // 检查文本节点是否在标题元素内
            const parentElement = target.parentElement;
            if (
              parentElement &&
              this.config.titleTags.includes(
                parentElement.nodeName.toLowerCase()
              )
            ) {
              shouldUpdate = true;
            }
          }
        }
      });

      // 如果有相关变化，更新菜单
      if (shouldUpdate) {
        // 使用防抖，避免频繁更新
        this.debouncedUpdateMenu();
      }
    });

    // 开始监听
    this.mutationObserver.observe(richTextBox, {
      childList: true, // 监听子节点变化
      subtree: true, // 监听所有后代节点
      characterData: true, // 监听文本内容变化
      attributes: true, // 监听属性变化
      attributeFilter: ["class", "style"], // 只监听特定属性
    });
  }

  // 防抖的菜单更新方法
  debouncedUpdateMenu = this.debounce(
    function () {
      console.log("墨滴插件: 检测到内容变化，更新菜单");
      this.updateMenu();
    }.bind(this),
    300
  );

  // 等待滚动完成
  waitForScrollComplete(callback) {
    const richTextBox = document.querySelector("#nice-rich-text-box");
    if (!richTextBox) return;

    let lastScrollTop = richTextBox.scrollTop;
    let scrollTimeout;

    const checkScroll = () => {
      const currentScrollTop = richTextBox.scrollTop;

      if (currentScrollTop === lastScrollTop) {
        // 滚动停止，执行回调
        clearTimeout(scrollTimeout);
        callback();
      } else {
        // 还在滚动，继续检查
        lastScrollTop = currentScrollTop;
        scrollTimeout = setTimeout(checkScroll, 50);
      }
    };

    // 开始检查滚动状态
    scrollTimeout = setTimeout(checkScroll, 50);
  }
}

// 创建插件实例并初始化
const mdniceTocPlugin = new MdniceTocPlugin();

// 页面加载完成后初始化
if (document.readyState === "loading") {
  document.addEventListener("DOMContentLoaded", () => {
    setTimeout(() => mdniceTocPlugin.init(), 100);
  });
} else {
  setTimeout(() => mdniceTocPlugin.init(), 100);
}

// 页面卸载时清理
window.addEventListener("beforeunload", () => {
  mdniceTocPlugin.destroy();
});
